package com.futureCloudMOM.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.futureCloudMOM.common.enums.DispatchStatus;
import com.futureCloudMOM.common.exception.base.BaseException;
import com.futureCloudMOM.core.base.service.impl.BaseServiceImpl;
import com.futureCloudMOM.core.domain.ProduceDispatch;
import com.futureCloudMOM.core.domain.ProduceReport;
import com.futureCloudMOM.core.domain.ProduceTaskBillSub;
import com.futureCloudMOM.core.mapper.ProduceDispatchMapper;
import com.futureCloudMOM.core.service.ProduceDispatchService;
import com.futureCloudMOM.core.service.ProduceTaskBillSubService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 【Produce_Dispatch】的数据库操作Service实现
 *
 * @author Administrator
 * @since 2023-06-06 16:02:32
 */
@Service
@AllArgsConstructor
public class ProduceDispatchServiceImpl extends BaseServiceImpl<ProduceDispatchMapper, ProduceDispatch> implements ProduceDispatchService {

    // 生产工单
    private final ProduceTaskBillSubService produceTaskBillSubService;


    @Override
    public boolean hasRunningDispatch(Long billId) {
        return countByBillIdAndStatus(billId, DispatchStatus.ONGOING.getStatus()) > 0;
    }

    @Override
    public Integer countByBillIdAndStatus(Long billId, Long status) {
        return count(new LambdaQueryWrapper<ProduceDispatch>().eq(ProduceDispatch::getTaskBillId, billId).eq(ProduceDispatch::getStatus, status));
    }

    /**
     * 传参是变更好的派工单信息，但是ID是被变更的派工单的ID
     * @param produceDispatch 变更的派工单信息
     */
    @Override
    @Transactional
    public void dispatchUpdate(ProduceDispatch produceDispatch) {
        //查询被调度的派工单的信息
        ProduceDispatch produceDispatch1 = getById(produceDispatch.getId());
        if(produceDispatch1.getStatus() == 0 || produceDispatch1.getStatus() == 1){
            // 可调度数量 = 派工单数量 - (报功合格数 + 报废数量)
            BigDecimal dispatchQty = produceDispatch1.getDispatchQty().subtract(produceDispatch1.getReportQty().add(produceDispatch1.getScrapQty()));
            if(dispatchQty.compareTo(BigDecimal.ZERO) == 0){
                throw new BaseException("该派工单可调度数量为【0】");
                // 调度数量必须大于0，且最大值不能超过可派工数量
            }else if (produceDispatch.getDispatchQty().compareTo(BigDecimal.ZERO) > 0 && dispatchQty.compareTo(produceDispatch.getDispatchQty()) >= 0){
                // 若调度数量 = 派工数量 则认为该派工单还未开工 派工单整体调度
                if (produceDispatch.getDispatchQty().compareTo(produceDispatch1.getDispatchQty()) == 0){
                    // 根据ID直接更新派工单数据
                    updateById(produceDispatch);
                    // 否则进行派工单拆分
                }else {
                    // 新派工单新增
                    save(produceDispatch);
                    // 老派工单核销掉调度数量
                    produceDispatch1.setDispatchQty(produceDispatch1.getDispatchQty().subtract(produceDispatch.getDispatchQty()));
                    // 老派工单的报工数量如果大于等于调度后的派工数量 派工单状态直接改为已完成
                    if(produceDispatch1.getReportQty().compareTo(produceDispatch1.getDispatchQty()) >= 0){
                        produceDispatch1.setStatus(2L);
                    }
                    // 更新老派工单数据
                    updateById(produceDispatch1);
                }

            }else{
                throw new BaseException("请核对调度数量是否超过可调度数量");
            }
        }else{
            throw new BaseException("派工单状态为待开工或生产中,才可以进行调度操作");
        }

    }

    @Override
    @Transactional
    public void forceStop(Long id) {
        // 根据ID查询该派工单最新状态
        ProduceDispatch produceDispatch = getById(id);
        // 验证状态是否可以进行关闭
        if(produceDispatch.getStatus() == 0 || produceDispatch.getStatus() == 1){
            // 派单数量改为已汇报数量
            produceDispatch.setDispatchQty(produceDispatch.getReportQty());
            // 派工单状态改为强制关闭
            produceDispatch.setStatus(3L);
            // 计算要释放的数量 = 派单数量 - 已汇报数量
            BigDecimal qty = produceDispatch.getDispatchQty().subtract(produceDispatch.getReportQty());
            // 释放的数量回归到生产工单
            ProduceTaskBillSub produceTaskBillSub = produceTaskBillSubService.getById(produceDispatch.getTaskBillSubId());
            produceTaskBillSub.setDispatchQty(produceTaskBillSub.getDispatchQty().subtract(qty));
            // 生产工单状态改为待派工
            produceTaskBillSub.setStatus(0L);
            produceTaskBillSubService.updateById(produceTaskBillSub);
            // 更新派工单
            updateById(produceDispatch);
        }else{
            throw new BaseException("派工单状态为待开工或生产中,才可以进行强制关闭操作");
        }
    }

    @Override
    public List<ProduceDispatch> dispatchListByBillTaskSubId(Long id) {
        return list(new LambdaQueryWrapper<ProduceDispatch>()
        .eq(ProduceDispatch::getTaskBillSubId,id));
    }

    @Override
    public void reportWrite(ProduceReport produceReport) {
        // 根据id获取派工单信息
        ProduceDispatch produceDispatch = getById(produceReport.getDispatchID());
        // 报工数量回写给派工单
        // 合格
        produceDispatch.setReportQty(produceDispatch.getReportQty().add(produceReport.getQty()));
        // 不良
        produceDispatch.setReworkQty(produceDispatch.getReworkQty().add(produceReport.getReworkQty()));
        // 报废
        produceDispatch.setScrapQty(produceDispatch.getScrapQty().add(produceReport.getScrapQty()));
        // 判断报工数量是否满足任务派单数量 满足则派工单状态改为已完成
        if(produceDispatch.getReportQty().compareTo(produceDispatch.getDispatchQty()) >= 0){
            produceDispatch.setStatus(2L);
        }
        updateById(produceDispatch);
    }


}
